<?php
declare (strict_types=1);

namespace addons\Builder\driver;

use think\Exception;
use think\facade\Cache;
use think\facade\Console;

class TableCache
{

    /**
     * @param $data
     * @param $key
     * 原点 2023年1月28日16:02:04 设置搜索内容
     */
    public function setData($data, $key)
    {
        Cache::set('tableCache_' . $key, $data);
    }

    /**
     * @return array
     * 原点 2023年1月28日16:02:46 获取搜索内容
     */
    public function getData($key = ''): array
    {
        $key = $key ?: $this->getTableUniqueStr();
        return Cache::get('tableCache_' . $key) ?: [];
    }

    /**
     * @param $key
     * @param $field
     * @return mixed
     * @throws Exception
     * 原点 2023年1月28日16:02:46 获取表格Field字段
     */
    public function getTableField($key, $field = '')
    {
        $tableField = Cache::get('tableField_' . $key);
        if (empty($tableField)) {
            throw new Exception('未查询到当前表格的字段！');
        }
        if ($field) {
            foreach ($tableField as $item) {
                if ($item['field'] == $field) {
                    return $item;
                }
            }
            throw new Exception('未匹配到指定field字段');
        } else {
            return $tableField;
        }

    }

    /**
     * @param $key
     * @param $data
     * @return void
     * 原点 2023年2月21日09:37:05 设置当前表格Field字段
     */
    public function setTableField($key, $data)
    {
        Cache::set('tableField_' . $key, $data);
    }

    /**
     * @param $table
     * @param $key
     * @param $cache
     * @return array[]|mixed
     * 原点 2023年2月21日09:37:30 设置当前表格编辑/新增字段
     */
    public function setModify($table, $key, $cache = false)
    {
        if ($cache) {
            $result = Cache::get('modify_' . $key);
            if ($result) return $result;
        }
        $add = [];
        $edit = [];
        $field = [];
        $unite = [];

        $controller = $this->resolving();
        foreach ($table as $v) {
            if (!isset($v['field']) || !$v['field']) continue;
            $field[] = ['title' => $v['title'], 'field' => $v['field']];
            if (isset($v['modify'])) {
                $modify = explode(',', $v['modify']);
                $element = [
                    'mode'        => $modify[0],
                    'type'        => $modify[1],
                    'title'       => $v['title'],
                    'field'       => $v['field'],
                    'placeholder' => isset($v['placeholder']) ? $v['title'] . $v['placeholder'] : $v['title']
                ];
                if (in_array($modify[1], ['select', 'radio', 'checkbox'])) {
                    $action = $modify[2];
                    $element['value'] = $controller::$action();
                }
                if (in_array($modify[1], ['img', 'video'])) {
                    $element['value'] = isset($modify[2]) ? $modify[2] : 1;
                }
                switch ($modify[0]) {
                    case 1:
                        $add[] = $element;
                        break;
                    case 2:
                    case 3:
                        $add[] = $element;
                        $edit[] = $element;
                        break;
                    case 4:
                        $edit[] = $element;
                        break;
                }
                if (!empty($v['unite'])) {
                    $action = $v['unite'];
                    $unite[] = ['key' => $v['field'], 'value' => $controller::$action()];
                }
            }
        }
        Cache::set('modify_' . $key, ['add' => $add, 'edit' => $edit, 'unite' => $unite]);
        $this->setTableField($key, $field);
        return ['add' => $add, 'edit' => $edit, 'unite' => $unite];
    }

    public function resolving()
    {
        $url = explode('@', request()->rule()->getName());
        return count($url) > 1 ? $url[0] : "\app\\" . app('http')->getName() . "\\controller\\" . request()->controller();
    }

    /**
     * @param $type
     * @param $key
     * @return array|mixed
     * 原点 2023年2月21日09:31:40 获取可编辑/添加字段
     */
    public function getModify($type = 'add', $key = ''): array
    {
        $key = $key ?: $this->getTableUniqueStr();
        $modify = Cache::get('modify_' . $key);
        return $modify && isset($modify[$type]) ? $modify[$type] : [];
    }

    /**
     * @return string
     * 原点 2023年2月21日09:38:29 获取当前访问url
     */
    public function getMethodUrl()
    {
        return strtolower(app('http')->getName() . '_' . request()->controller . '_' . request()->action);
    }

    /**
     * @return array|mixed|string
     * 原点 2023年2月21日09:38:11 获取当前表格唯一的标识
     */
    public function getTableUniqueStr()
    {
        return request()->param('tableUniqueStr') ?: $this->getMethodUrl();
    }

    /**
     * @param $data
     * @param $key
     * 原点 2023年1月28日16:16:30 设置额外搜索内容
     */
    public function setExtraMap($data, $key)
    {
        Cache::set('tableExtraMap_' . $key, $data);
    }

    /**
     * @return array
     * 原点 2023年1月28日16:20:21 获取额外查询条件
     */
    public function getExtraMap(): array
    {
        return Cache::get('tableExtraMap_' . $this->getTableUniqueStr());
    }

    public function getView($view = 'index', $html = false, $arguments = []): string
    {

        $file = app()->getRootPath() . 'addons/Builder/view/' . $view . '.html';
        return $html ? \think\facade\View::fetch($file, $arguments) : $file;

    }

    public function createHtml($info = [], $form = [])
    {
        try {
            if ($form['type'] == 'search') {
                return $this->getView('items/' . $form['type'], true, ['search' => $info]);
            }
            $title = $form['title'];
            $field = $form['field'];
            $placeholder = $form['placeholder'];
            $value = isset($info) && $info ? $info->getData($form['field']) : '';
            if ($value) {
                $mode = $form['mode'] == 3 ? 'disabled' : '';
            } else {
                $mode = '';
            }
            $html = ' <div class="layui-col-xs12 layui-col-sm12 layui-col-md6"><div class="layui-form-item" id="AUTO-' . $field . '">';
            if ($form['type'] == 'editor') {
                $html = '<div class="layui-form-item" id="AUTO-' . $field . '" style="width: 100%">';
            }
            $html .= '<label class="layui-form-label">' . $title . ' </label>';
            switch ($form['type']) {
                case "input":
                case "number":
                case "password":
                    $html .= '<div class="layui-input-block">';
                    $type = $form['type'] == 'input' ? 'text' : $form['type'];
                    $value = $form['type'] == 'password' ? '' : $value;
                    $html .= '<input type="' . $type . '" name="' . $field . '" value="' . $value . '" placeholder="请输入' . $placeholder . '" lay-verify="required" class="layui-input" ' . $mode . '/>';
                    $html .= '</div>';
                    break;
                case "ratio":
                    $html .= '<div class="layui-input-block">';
                    $html .= '<input type="number" name="' . $field . '" value="' . $value * 100 . '" placeholder="请输入' . $title . '" lay-verify="required" class="layui-input" ' . $mode . '/>';
                    $html .= '</div><div class="layui-form-mid layui-word-aux">%</div>';
                    break;
                case "checkbox":
                    $html .= '<div class="layui-input-block">';
                    $dataId = [];
                    if (!empty($info)) $dataId = explode(',', $info->getData($form['field']));
                    foreach ($form['value'] as $k => $v) {
                        $checked = in_array($k, $dataId) ? "checked" : '';
                        $html .= '<input type = "checkbox" name = "' . $field . '[]" value = "' . $k . '" title = "' . $v . '" ' . $checked . ' >';
                    }
                    $html .= '</div>';
                    break;
                case "radio":
                    $html .= '<div class="layui-input-block">';
                    if (empty($info)) {
                        foreach ($form['value'] as $k => $v) {
                            $html .= '<input type="radio" name="' . $field . '"  value="' . $k . '" title="' . $v . '" ' . $mode . '>';
                        }
                    } else {
                        foreach ($form['value'] as $k => $v) {
                            $checked = $value == $k ? 'checked' : '';
                            $html .= '<input type="radio" name="' . $field . '"  value="' . $k . '" title="' . $v . '" ' . $checked . ' ' . $mode . '>';
                        }
                    }
                    $html .= '</div>';
                    break;
                case "select":
                    $html .= '<div class="layui-input-block"><select lay-search="" lay-filter="' . $field . '" name="' . $field . '">';
                    if (empty($info)) {
                        foreach ($form['value'] as $k => $v) {
                            $html .= '<option value="' . $k . '" ' . $mode . '>' . $v . '</option>';
                        }
                    } else {
                        foreach ($form['value'] as $k => $v) {
                            $selected = $value == $k ? 'selected' : '';
                            $html .= '<option value="' . $k . '" ' . $selected . ' ' . $mode . '>' . $v . '</option>';
                        }
                    }
                    $html .= '</select></div>';
                    break;
                case "textarea":
                    $html .= '<div class="layui-input-block">';
                    $html .= '<textarea name="' . $field . '" placeholder="请输入' . $title . '" class="layui-textarea">' . $value . '</textarea>';
                    $html .= '</div>';
                    break;
                default:
                    $style = $form['type'] == 'editor' ? 'word-break: break-all;' : '';
                    $html .= '<div class="layui-input-block" style="' . $style . '">';
                    $html .= $this->getView('items/' . $form['type'], true, ['form' => $form, 'info' => $info]);
                    $html .= '</div>';
                    break;
            }
            $html .= '</div></div>';
            return $html;
        } catch (\Exception $e) {

            throw new \Exception($e->getMessage());
        }

    }

    public static function analysisComment($text): array
    {
        try {
            $data = [];
            //解析title
            preg_match_all('/[\x{4e00}-\x{9fff}]+/u', $text, $result);
            $data['title'] = !empty($result[0][0]) ? $result[0][0] : $text;
            //解析()
            preg_match_all("/(?:\()(.*)(?:\))/i", $text, $result);
            $data['modify'] = $result[1] ? $result[1][0] : '';
            //解析[]
            preg_match_all("/(?:\[)(.*)(?:\])/i", $text, $result);
            $brackets = $result[1] ? self::analysisBrackets($result[1][0]) : [];
            $data = array_merge($data, $brackets);
            return $data;
        } catch (\Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

    public static function analysisBrackets($text)
    {
        $brackets = [];
        if (!$text) return $brackets;
        $step1 = explode(',', $text);
        foreach ($step1 as $item) {
            $step2 = explode(':', $item);
            $brackets[$step2[0]] = $step2[1];
        }

        return $brackets;
    }

    public function autoCM($param)
    {
        try {
            if (isset($param['autoController']) && $param['autoController']) {
                if (!$param['className'] || !$param['classNamespace']) {
                    return ['code' => -1, 'msg' => '已开启自动构建控制器，请填写控制器相关参数'];
                }
                if ($param['autoController'] == '1') {
                    Console::call('_controller', [$param['classNamespace'] . $param['className']]);
                } else {
                    Console::call('_autoController', [$param['classNamespace'] . $param['className']]);
                    //写入路由
                    $key = lcfirst($param['className']);
                    $a = "//" . $param['title'] . "
Route::group('" . $key . "', function () {
    Route::get('/index', '" . $key . "/index');
    Route::get('/getList', '" . $key . "/getList');
    Route::get('/add', '" . $key . "/add');
    Route::get('/edit', '" . $key . "/edit');
    Route::post('/save', '" . $key . "/save');
    Route::post('/update', '" . $key . "/update');
    Route::post('/delete', '" . $key . "/delete');
})->middleware('verify');";
                    file_put_contents(app()->getBasePath() . 'admin/route/app.php', $a, FILE_APPEND);
                }
            }
            //自动构建模型
            if (isset($param['autoModel']) && $param['autoModel'] == '1') {
                if (!$param['modelName'] || !$param['modelNamespace'] || !$param['dbName']) {
                    return ['code' => -1, 'msg' => '已开启自动构建模型，请填写模型相关参数'];
                }
                Console::call('_model', [$param['modelNamespace'] . $param['modelName'] . ',' . $param['dbName']]);
            }
            return ['code' => 1, 'msg' => 'success'];
        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    /**
     * @return array
     * 原点 2023年5月13日16:06:22 获取附加菜单
     */
    public function getAttachMenu(): array
    {
        $menu = Cache::get('builderAttachMenu');
        if (!$menu) {
            include app()->getRootPath() . 'addons' . DIRECTORY_SEPARATOR . 'Builder' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'builder.php';
            $menu = attachMenu();
            Cache::set('builderAttachMenu', $menu);
        }
        return $menu;
    }

}
